//
// DotNetNuke - http://www.dotnetnuke.com
// Copyright (c) 2002-2010
// by Perpetual Motion Interactive Systems Inc. ( http://www.perpetualmotion.ca )
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 
// documentation files (the "Software"), to deal in the Software without restriction, including without limitation 
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and 
// to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions 
// of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 
// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 
// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
// DEALINGS IN THE SOFTWARE.
//

using System;
using System.IO;
using System.Web.UI.WebControls;
using System.Xml;
using DotNetNuke.Entities.Modules;
using DotNetNuke.Entities.Tabs;
using DotNetNuke.UI.Skins;
namespace DotNetNuke.Modules.Admin.Skins
{
	partial class Attributes : DotNetNuke.Entities.Modules.PortalModuleBase
	{
		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			cboContainers.SelectedIndexChanged += new EventHandler(cboContainers_SelectedIndexChanged);
			cboFiles.SelectedIndexChanged += new EventHandler(cboFiles_SelectedIndexChanged);
			cboSettings.SelectedIndexChanged += new EventHandler(cboSettings_SelectedIndexChanged);
			cboSkins.SelectedIndexChanged += new EventHandler(cboSkins_SelectedIndexChanged);
			cboTokens.SelectedIndexChanged += new EventHandler(cboTokens_SelectedIndexChanged);
			cmdUpdate.Click += new EventHandler(cmdUpdate_Click);

			try {
				if (!Page.IsPostBack) {
					LoadSkins();
					LoadContainers();
				}
			} catch (Exception exc) {
				Services.Exceptions.Exceptions.ProcessModuleLoadException(this, exc);
			}
		}
		private void cboSkins_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			ShowSkins();
		}
		private void cboContainers_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			ShowContainers();
		}
		protected void cboFiles_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			LoadTokens();
		}
		protected void cboTokens_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			LoadSettings();
		}
		protected void cboSettings_SelectedIndexChanged(object sender, System.EventArgs e)
		{
			LoadValues();
		}
		private void cmdUpdate_Click(object sender, EventArgs e)
		{
			try {
				if (Page.IsValid) {
					UpdateSkin();
				}
			} catch (Exception exc) {
				Services.Exceptions.Exceptions.ProcessModuleLoadException(this, exc);
			}
		}
		private void ShowSkins()
		{
			string strSkinPath = Common.Globals.ApplicationMapPath.ToLower() + cboSkins.SelectedItem.Value;
			cboContainers.ClearSelection();
			if (cboSkins.SelectedIndex > 0) {
				LoadFiles(strSkinPath);
			}
		}
		private void ShowContainers()
		{
			string strContainerPath = Common.Globals.ApplicationMapPath.ToLower() + cboContainers.SelectedItem.Value;
			cboSkins.ClearSelection();
			if (cboContainers.SelectedIndex > 0) {
				LoadFiles(strContainerPath);
			}
		}
		private void LoadSkins()
		{
			string strRoot;
			string[] arrFolders;
			string strName;
			string strSkin;
			cboSkins.Items.Clear();
			cboSkins.Items.Add("<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
			if (UserInfo.IsSuperUser) {
				strRoot = Request.MapPath(Common.Globals.HostPath + SkinController.RootSkin);
				if (Directory.Exists(strRoot)) {
					arrFolders = Directory.GetDirectories(strRoot);
					foreach (string strFolder in arrFolders) {
						strName = strFolder.Substring(strFolder.LastIndexOf("\\") + 1);
						strSkin = strFolder.Replace(Common.Globals.ApplicationMapPath, "");
						if (strName != "_default") {
							cboSkins.Items.Add(new ListItem(strName, strSkin.ToLower()));
						}
					}
				}
			}
			strRoot = PortalSettings.HomeDirectoryMapPath + SkinController.RootSkin;
			if (Directory.Exists(strRoot)) {
				arrFolders = Directory.GetDirectories(strRoot);
				foreach (string strFolder in arrFolders)
				{
					strName = strFolder.Substring(strFolder.LastIndexOf("\\") + 1);
					strSkin = strFolder.Replace(Common.Globals.ApplicationMapPath, "");
					cboSkins.Items.Add(new ListItem(strName, strSkin.ToLower()));
				}
			}
		}
		private void LoadContainers()
		{
			string strRoot;
			string[] arrFolders;
			string strName;
			string strSkin;
			cboContainers.Items.Clear();
			cboContainers.Items.Add("<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
			if (UserInfo.IsSuperUser) {
				strRoot = Request.MapPath(Common.Globals.HostPath + SkinController.RootContainer);
				if (Directory.Exists(strRoot)) {
					arrFolders = Directory.GetDirectories(strRoot);
					foreach (string strFolder in arrFolders) {
						strName = strFolder.Substring(strFolder.LastIndexOf("\\") + 1);
						strSkin = strFolder.Replace(Common.Globals.ApplicationMapPath, "");
						if (strName != "_default") {
							cboContainers.Items.Add(new ListItem(strName, strSkin.ToLower()));
						}
					}
				}
			}
			strRoot = PortalSettings.HomeDirectoryMapPath + SkinController.RootContainer;
			if (Directory.Exists(strRoot)) {
				arrFolders = Directory.GetDirectories(strRoot);
				foreach (string strFolder in arrFolders) {
					strName = strFolder.Substring(strFolder.LastIndexOf("\\") + 1);
					strSkin = strFolder.Replace(Common.Globals.ApplicationMapPath, "");
					cboContainers.Items.Add(new ListItem(strName, strSkin.ToLower()));
				}
			}
		}
		private void LoadFiles(string strFolderPath)
		{
			cboFiles.Items.Clear();
			string[] arrFiles;
			if (Directory.Exists(strFolderPath)) {
				arrFiles = Directory.GetFiles(strFolderPath, "*.ascx");
				foreach (string strFile in arrFiles) {
					cboFiles.Items.Add(new ListItem(Path.GetFileNameWithoutExtension(strFile), strFile));
				}
			}
			cboFiles.Items.Insert(0, "<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
		}
		private void LoadTokens()
		{
			cboTokens.DataSource = SkinControlController.GetSkinControls().Values;
			cboTokens.DataBind();
			cboTokens.Items.Insert(0, "<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
		}
		private void LoadSettings()
		{
			cboSettings.Items.Clear();
			string strFile = Common.Globals.ApplicationMapPath + "\\" + cboTokens.SelectedItem.Value.ToLower().Replace("/", "\\").Replace(".ascx", ".xml");
			if (File.Exists(strFile)) {
				try {
					XmlDocument xmlDoc = new XmlDocument();
					xmlDoc.Load(strFile);
					foreach (XmlNode xmlSetting in xmlDoc.SelectNodes("//Settings/Setting")) {
						cboSettings.Items.Add(new ListItem(xmlSetting.SelectSingleNode("Name").InnerText, xmlSetting.SelectSingleNode("Name").InnerText));
					}
				} catch {
					UI.Skins.Skin.AddModuleMessage(this, "Error Loading Settings File For Object", UI.Skins.Controls.ModuleMessage.ModuleMessageType.RedError);
				}
			} else {
				UI.Skins.Skin.AddModuleMessage(this, "Object Selected Does Not Have Settings Defined", UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
			}
			cboSettings.Items.Insert(0, "<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
		}
		private void LoadValues()
		{
			cboValue.Items.Clear();
			txtValue.Text = "";
			string strFile = Common.Globals.ApplicationMapPath + "\\" + cboTokens.SelectedItem.Value.ToLower().Replace("/", "\\").Replace(".ascx", ".xml");
			if (File.Exists(strFile)) {
				try {
					XmlDocument xmlDoc = new XmlDocument();
					xmlDoc.Load(strFile);
					foreach (XmlNode xmlSetting in xmlDoc.SelectNodes("//Settings/Setting")) {
						if (xmlSetting.SelectSingleNode("Name").InnerText == cboSettings.SelectedItem.Value) {
							string strValue = xmlSetting.SelectSingleNode("Value").InnerText;
							switch (strValue) {
								case "":
									txtValue.Visible = true;
									cboValue.Visible = false;
									break;
								case "[TABID]":
									TabController objTabs = new TabController();
									foreach(Entities.Tabs.TabInfo objTab in objTabs.GetTabsByPortal(PortalId).Values)
									{
										cboValue.Items.Add(new ListItem(objTab.TabName, objTab.TabID.ToString()));
									}

									cboValue.Items.Insert(0, "<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
									cboValue.Visible = true;
									txtValue.Visible = false;
									break;
								default:
									string[] arrValues = (strValue + ",").Split(',');
									foreach (string value in arrValues) {
										if (!String.IsNullOrEmpty(value)) {
											cboValue.Items.Add(new ListItem(value, value));
										}
									}

									cboValue.Items.Insert(0, "<" + Services.Localization.Localization.GetString("Not_Specified") + ">");
									cboValue.Visible = true;
									txtValue.Visible = false;
									break;
							}
							lblHelp.Text = xmlSetting.SelectSingleNode("Help").InnerText;
						}
					}
				} catch {
					UI.Skins.Skin.AddModuleMessage(this, "Error Loading Settings File For Object", UI.Skins.Controls.ModuleMessage.ModuleMessageType.RedError);
				}
			} else {
				UI.Skins.Skin.AddModuleMessage(this, "Object Selected Does Not Have Settings Defined", UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
			}
		}
		private void UpdateSkin()
		{
			if (cboSettings.SelectedIndex > 0) {
				if ((cboValue.SelectedItem != null) || !String.IsNullOrEmpty(txtValue.Text))
				{
					StreamReader objStreamReader;
					objStreamReader = File.OpenText(cboFiles.SelectedItem.Value);
					string strSkin = objStreamReader.ReadToEnd();
					objStreamReader.Close();
					string strTag = "<dnn:" + cboTokens.SelectedItem.Text + " runat=\"server\" id=\"dnn" + cboTokens.SelectedItem.Text + "\"";
					int intOpenTag = strSkin.IndexOf(strTag);
					if (intOpenTag != -1) {
						int intCloseTag = strSkin.IndexOf(" />", intOpenTag);
						string strAttribute = cboSettings.SelectedItem.Value;
						int intStartAttribute = strSkin.IndexOf(strAttribute, intOpenTag);
						string strValue = "";
						if (cboValue.Visible) {
							strValue = cboValue.SelectedItem.Value;
						} else {
							strValue = txtValue.Text;
						}
						if (intStartAttribute != -1 && intStartAttribute < intCloseTag) {
							int intEndAttribute = strSkin.IndexOf("\" ", intStartAttribute);
							strSkin = strSkin.Substring(0, intStartAttribute) + strSkin.Substring(intEndAttribute + 2);
						}
						strSkin = strSkin.Insert(intOpenTag + strTag.Length, " " + strAttribute + "=\"" + strValue + "\"");
						try {
							File.SetAttributes(cboFiles.SelectedItem.Value, FileAttributes.Normal);
							StreamWriter objStream;
							objStream = File.CreateText(cboFiles.SelectedItem.Value);
							objStream.WriteLine(strSkin);
							objStream.Close();
							UpdateManifest();
							UI.Skins.Skin.AddModuleMessage(this, "Skin Successfully Updated", UI.Skins.Controls.ModuleMessage.ModuleMessageType.GreenSuccess);
						} catch {
							UI.Skins.Skin.AddModuleMessage(this, "Error Updating Skin File", UI.Skins.Controls.ModuleMessage.ModuleMessageType.RedError);
						}
					} else {
						UI.Skins.Skin.AddModuleMessage(this, "Selected File Does Not Contain Token", UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
					}
				} else {
					UI.Skins.Skin.AddModuleMessage(this, "You Must Specify A Value For The Setting", UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
				}
			} else {
				UI.Skins.Skin.AddModuleMessage(this, "You Must Select A Token Setting", UI.Skins.Controls.ModuleMessage.ModuleMessageType.YellowWarning);
			}
		}
		private void UpdateManifest()
		{
			if (File.Exists(cboFiles.SelectedItem.Value.Replace(".ascx", ".htm"))) {
				string strFile = cboFiles.SelectedItem.Value.Replace(".ascx", ".xml");
				if (File.Exists(strFile) == false) {
					strFile = strFile.Replace(Path.GetFileName(strFile), "skin.xml");
				}
				XmlDocument xmlDoc = null;
				try {
					xmlDoc = new XmlDocument();
					xmlDoc.Load(strFile);
				} catch {
					xmlDoc.InnerXml = "<Objects></Objects>";
				}
				XmlNode xmlToken = xmlDoc.DocumentElement.SelectSingleNode("descendant::Object[Token='[" + cboTokens.SelectedItem.Text + "]']");
				if (xmlToken == null) {
					string strToken = "<Token>[" + cboTokens.SelectedItem.Text + "]</Token><Settings></Settings>";
					xmlToken = xmlDoc.CreateElement("Object");
					xmlToken.InnerXml = strToken;
					xmlDoc.SelectSingleNode("Objects").AppendChild(xmlToken);
					xmlToken = xmlDoc.DocumentElement.SelectSingleNode("descendant::Object[Token='[" + cboTokens.SelectedItem.Text + "]']");
				}
				string strValue = "";
				if (cboValue.Visible) {
					strValue = cboValue.SelectedItem.Value;
				} else {
					strValue = txtValue.Text;
				}
				bool blnUpdate = false;
				foreach (XmlNode xmlSetting in xmlToken.SelectNodes(".//Settings/Setting")) {
					if (xmlSetting.SelectSingleNode("Name").InnerText == cboSettings.SelectedItem.Value) {
						xmlSetting.SelectSingleNode("Value").InnerText = strValue;
						blnUpdate = true;
					}
				}
				if (blnUpdate == false) {
					string strSetting = "<Name>" + cboSettings.SelectedItem.Value + "</Name><Value>" + strValue + "</Value>";
					XmlNode xmlSetting = xmlDoc.CreateElement("Setting");
					xmlSetting.InnerXml = strSetting;
					xmlToken.SelectSingleNode("Settings").AppendChild(xmlSetting);
				}
				try {
					if (File.Exists(strFile)) {
						File.SetAttributes(strFile, FileAttributes.Normal);
					}
					StreamWriter objStream;
					objStream = File.CreateText(strFile);
					string strXML = xmlDoc.InnerXml;
					strXML = strXML.Replace("><", ">" + Environment.NewLine + "<");
					objStream.WriteLine(strXML);
					objStream.Close();
				} catch {
				}
			}
		}
	}
}
